package com.fast.ThreadPoolFactory;

import cn.hutool.core.thread.NamedThreadFactory;

import java.util.concurrent.*;

/**
 * CompletableFuture
 * whenComplete 任务执行成功时调用，可以收到异常信息，但无法捕获
 * exceptionally 任务执行失败时调用，不管是前面哪一步报错都能捕获到
 *
 * 推荐：handle((res,exception)->{return 10;})包含whenComplete和exceptionally，无论执行成功还是失败，都能修改返回结果
 *
 * @author hjw
 * @since 2022年07月17日 17:00:00
 */
public class CF2_whenComplete_exceptionally{
    public static ThreadPoolExecutor threadPoolExecutor =  new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors() * 2,
            Runtime.getRuntime().availableProcessors() * 2,
            10,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(300),
            new NamedThreadFactory("core_thread_pool_",true),
            new ThreadPoolExecutor.AbortPolicy()
    );

    //handle((res,exception)->{return 10;})包含whenComplete和exceptionally，无论执行成功还是失败，都能修改返回结果
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //A任务做完，同步接着做B，
        System.out.println("主线程开始了----------");
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("1线程"+Thread.currentThread().getName()+"把A任务执行了");
            int i = 10 / 1;
//            int i = 10 / 2;
            return i;
        }, threadPoolExecutor).whenComplete((result, exception) -> {
            int i = 10/0;
            System.out.println("1A任务执行成功之后用线程"+Thread.currentThread().getName()+"执行B任务");
            //whenComplete:和Main使用同一个线程执行，可以捕获异常，不阻塞main线程，但是无法处理，异常时无法返回默认值
            System.out.println("1result = " + result);
            System.out.println("1exception = " + exception);
        }).exceptionally((result)->{
            //当上面A和B有一个执行异常时，可以指定返回一个默认值，不阻塞main线程
            System.out.println("1A任务执行失败之后执行 result = " + result);
            return 100;
        });;
        System.out.println("future1的执行结果 = " + future1.get());

        System.out.println("主线程结束了");
    }
}
